密封類別的用法是加上一個關鍵字sealed
在類別或是特徵之前
而sealed class
的用途是什麼?
簡單來說,密封類別會用來限制類別和特徵的繼承,防止繼承濫用。
將類別或特徵宣告為sealed
可以限制我們定義其子類別的位置,必須定義在其類別定義的相同source file中,也就是說不能在類別定義的file以外定義任何新的子類別。
A sealed class cannot have any new subclasses added except the ones in the same file.
第二個用途是用在模式比對
假設我們在寫一個pattern match,必須確保有涵蓋到所有可能的cases。
有時我們會選擇加一個default case在match運算式的最後,不過有時候還是會出現錯誤,這時我們就可以case class的父類別宣告為sealed
。
If you match against case classes that inherit from a sealed class, the compiler will flag missing combinations of patterns with a warning message.
abstract class Animal
case class Dog extends Animal
case class Cat extends Animal
case class Bird extends Animal
def test(x: Any) =
x match
case Dog => println("bark")
case Cat => println("meow")
//少寫一個Bird case
這時編譯器會給出警告,因為我們沒有全部列出案例類別warning: match is not exhaustive!
對於要進行模式比對時一定要出現的案例類別,我們可以將其繼承的父類別進行密封(sealed)
sealed abstract class Animal
case class Dog extends Animal
case class Cat extends Animal
case class Bird extends Animal
如果說案例類型只想要其中幾個,而complier會對我們沒有全部列出給出警告,這時我們可以使用萬用字元模式
def test(x: Any) =
x match
case Dog => println("bark")
case Cat => println("meow")
case _ => throw new RuntimeException
不過這樣的程式不夠理想,只為了讓complier不要給出警告,程式可能被強加了永遠不會執行到的code。
這時提供另一個方法,就是加上@unchecked
註解到match運算式
def test(x: Any) =
(x: @unchecked) match
case Dog => println("bark")
case Cat => println("meow")